package com.arui.springsecuritystudy.utils;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
import java.util.Date;
import java.util.Objects;
import java.util.UUID;

/**
 * @description:
 * @author: zyr
 * @date: 2024/3/29 15:49
 */
public class JwtUtil {
    /**
     * 秘钥铭文
     */
    public static final String JWT_KEY = "zyr";
    /**
     * 默认过期时间，一个小时
     */
    public static final Long JWT_TTL = 60 * 60 *1000L;

    /**
     * 生产jwt
     *
     * @param subject token保存的数据（json格式）
     * @return token字符串
     */
    public static String createJWT(String subject) {
        final JwtBuilder builder = getJwtBuilder(subject, null, getUUID());
        return builder.compact();
    }

    /**
     * 生成jwt
     *
     * @param subject token保存的数据（json格式）
     * @param millis token过期时间（毫秒）
     * @return token字符串
     */
    public static String createJWT(String subject, Long millis) {
        final JwtBuilder builder = getJwtBuilder(subject, millis, getUUID());
        return builder.compact();
    }

    /**
     * 生成jwt
     *
     * @param id 生成token所需id
     * @param subject token过期时间（毫秒）
     * @param millis token过期时间（毫秒）
     * @return 唯一token
     */
    public static String createJWT(String id, String subject, Long millis) {
        JwtBuilder builder = getJwtBuilder(subject, millis, id);// 设置过期时间
        return builder.compact();
    }

    private static JwtBuilder getJwtBuilder(String subject, Long millis, String uuid) {
        final SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
        final SecretKey secretKey = generateSecretKey();
        long nowMillis = System.currentTimeMillis();
        final Date now = new Date();
        if (Objects.isNull(millis)) {
            millis = JWT_TTL;
        }
        final long expireMillis = nowMillis + millis;
        final Date expireDate = new Date(expireMillis);
        return Jwts.builder()
                .setId(uuid)                               // 唯一的ID
                .setSubject(subject)                       // 主题 可以是JSON数据
                .setIssuer("zyr")                          // 签发者
                .setIssuedAt(now)                          // 签发时间
                .signWith(signatureAlgorithm, secretKey)   // 使用HS256对称加密算法签 名, 第二个参数为秘钥
                .setExpiration(expireDate);                // 过期时间
    }

    /**
     * 生成加密后的密钥
     */
    private static SecretKey generateSecretKey() {
        final byte[] encodeKey = Base64.getDecoder().decode(JwtUtil.JWT_KEY);
        return new SecretKeySpec(encodeKey, 0, encodeKey.length, "AES");
    }

    /**
     * 获取随机的唯一的uuid
     */
    private static String getUUID() {
        return UUID.randomUUID().toString().replaceAll("-", "");
    }

    public static void main(String[] args) {
        String jwt = JwtUtil.createJWT("1");
        Claims claims = JwtUtil.parseJWT(jwt);
        System.out.println(jwt);
        System.out.println(claims.getSubject());
    }

    /**
     * 解析jwt
     *
     * @param jwt 需要解析的jwt
     */
    public static Claims parseJWT(String jwt) {
        final SecretKey secretKey = generateSecretKey();
        return Jwts.parser()
                .setSigningKey(secretKey)
                .parseClaimsJws(jwt)
                .getBody();
    }
}
